#pragma once

#include <iostream>
#include<vector>
#include"Sem.hpp"
#include"Mutex.hpp"
static int gcap=5;

template<typename T>
class RingQueue
{
public:
    RingQueue(int cap=gcap):_cap(cap),_ring_queue(cap),_space_sem(cap),_data_sem(0),_p_step(0),_c_step(0)
    {

    }
    void Pop(T* out)
    {
        _data_sem.P();
        {
            LockGuard LockGuard(&_c_lock);
            //消费数据
            *out=_ring_queue[_c_step++];
            _c_step%=_cap;
        }
        _space_sem.V();
    }
    void EnQueue(const T& in)
    {

        _space_sem.P();
        {
            LockGuard LockGuard(&_p_lock);
            //生产数据
            _ring_queue[_p_step++]=in;
            _p_step%=_cap;
        }
        _data_sem.V();//释放信号量没必要在临界区中，咱们的临界区范围要尽可能地小

    }
    ~RingQueue()
    {

    }

private:
    std::vector<T> _ring_queue;//临界资源
    int _cap;//容量

    //描述资源数量
    Sem _space_sem;
    Sem _data_sem;

    //生产和消费的位置
    int _p_step;
    int _c_step;

    Mutex _p_lock;
    Mutex _c_lock;
};